//
//  Function.m
//  PinkOK
//
//  Created by BenyLiang on 13-8-7.
//  Copyright (c) 2013年 PinkOK. All rights reserved.
//  核心函数库

#import "IMFunction.h"
#import <CommonCrypto/CommonDigest.h>
#import <AVFoundation/AVFoundation.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include "adpcm.h"
#import "Keychain.h"
#import "IMTConfig.h"
#import "KSLanguageManager.h"
#include "aes128_ecb.h"
#import "CarModel.h"

#define AESKEY {0xA2,0x3C,0xBC,0x5F,0x11,0x4B,0xA1,0xD5,0x42,0x26,0xE6,0x39,0x9E,0xB3,0x2F,0xD1}
#define AESIV {0xA2,0x3C,0xBC,0x5F,0x11,0x4B,0xA1,0xD5,0x42,0x26,0xE6,0x39,0x9E,0xB3,0x2F,0xD1}


@implementation IMFunction

// 加密
+ (NSData *)AES128EncryptECB:(NSData *)plainText {
    uint8_t s_key1[16] = AESKEY;
    uint8_t random[16] = {0x00};
    [plainText getBytes:&random length:plainText.length];
    uint8_t s_encrypted_random_key1[16] = {0};   //加密后的数据
    uint8_t ekey[176];
    memcpy(s_encrypted_random_key1, random, 16);
    AES128_ECB_KeyExpand((uint8_t *)s_key1, ekey);     //s_key1 = 密钥1
    AES128_ECB_Encrypt(ekey, s_encrypted_random_key1);
    NSData *result = [NSData dataWithBytes:s_encrypted_random_key1 length:16];
    return result;
}

// 解密
+ (NSData *)AES128DecryptECB:(NSData *)encryptText {
    uint8_t s_key1[16] = AESIV;
    uint8_t random[16] = {0x00};
    [encryptText getBytes:&random length:encryptText.length];
    uint8_t s_encrypted_random_key1[16] = {0};   //解密后的数据
    uint8_t ekey[176];
    memcpy(s_encrypted_random_key1, random, 16);
    AES128_ECB_KeyExpand((uint8_t *)s_key1, ekey);     //s_key1 = 密钥1
    AES128_ECB_Decrypt(ekey, s_encrypted_random_key1);
    NSData *result = [NSData dataWithBytes:s_encrypted_random_key1 length:16];
    return result;
}

//获取设备高度
+ (CGFloat)getDeviceWidth {
    return (double) [[UIScreen mainScreen] bounds].size.width;
}

//MD5加密
+ (NSString *)md5:(NSString *)string {
    if (string) {
        const char *cStr = [string UTF8String];
        unsigned char result[32];
        CC_MD5(cStr, strlen(cStr), result);
        return [NSString stringWithFormat:
                @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", result[0], result[1], result[2], result[3],
                result[4], result[5], result[6], result[7],
                result[8], result[9], result[10], result[11],
                result[12], result[13], result[14], result[15]];
    }
    return nil;
}

//统计中英文混合的字符串长度
+ (int)lengthOfString:(NSString *)strtemp {
    int strlength = 0;
    char *p = (char *) [strtemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i = 0; i < [strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++) {
        if (*p) {
            p++;
            strlength++;
        }
        else {
            p++;
        }
    }
    return (strlength + 1) / 2;
    
}

+ (CGFloat)getLabelHeightWithText:(NSString *)text andFont:(UIFont *)font andLabelWidth:(CGFloat)width {
    CGSize size = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : font} context:nil].size;
    return ceil(size.height);
}

+ (CGFloat)getLabelHeightWithText:(NSString *)text font:(UIFont *)font lineSpacing:(CGFloat)spacing andLabelWidth:(CGFloat)width {
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    style.lineSpacing = spacing;
    NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName: style};
    CGSize size = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
    return ceil(size.height);
}

+ (CGFloat)getLabelWidthWithText:(NSString *)text andFont:(UIFont *)font andLabelWidth:(CGFloat)width {
    CGSize size = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName : font} context:nil].size;
    
    return size.height;
    
}

//获取当前IP地址
+ (NSString *)getIPAddress {
    NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if (temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en1"]) {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *) temp_addr->ifa_addr)->sin_addr)];
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    
    // Free memory
    freeifaddrs(interfaces);
    
    return address;
}

+ (UIImageView *)rotate360DegreeWithImageView:(UIImageView *)imageView {
    CABasicAnimation *animation = [CABasicAnimation
                                   animationWithKeyPath:@"transform"];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    //围绕Z轴旋转，垂直与屏幕
    animation.toValue = [NSValue valueWithCATransform3D:
                         CATransform3DMakeRotation(M_PI, 0.0, 0.0, 1.0)];
    animation.duration = 1;
    //旋转效果累计，先转180度，接着再旋转180度，从而实现360旋转
    animation.cumulative = NO;
    animation.repeatCount = 0;
    
    [imageView.layer addAnimation:animation forKey:nil];
    return imageView;
}

+ (NSString *)toHex:(u_int64_t)tmpid {
    NSString *nLetterValue;
    NSString *str = @"";
    long long int ttmpig;
    for (int i = 0; i < 36; i++) {
        ttmpig = tmpid % 16;
        tmpid = tmpid / 16;
        switch (ttmpig) {
            case 10:
                nLetterValue = @"A";
                break;
            case 11:
                nLetterValue = @"B";
                break;
            case 12:
                nLetterValue = @"C";
                break;
            case 13:
                nLetterValue = @"D";
                break;
            case 14:
                nLetterValue = @"E";
                break;
            case 15:
                nLetterValue = @"F";
                break;
            default:
                nLetterValue = [[NSString alloc] initWithFormat:@"%llu", ttmpig];
        }
        str = [nLetterValue stringByAppendingString:str];
        if (tmpid == 0) {
            break;
        }
    }
    
    //补足16位
    NSUInteger len = str.length;
    for (int i = 0; i < (16 - len); i++) {
        str = [NSString stringWithFormat:@"0%@", str];
    }
    return str;
}

+ (NSString *)decodeHTMLString:(NSString *)string {
    
    string = [string stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"];
    string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
    string = [string stringByReplacingOccurrencesOfString:@"&#39;" withString:@"'"];
    string = [string stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\\"];
    string = [string stringByReplacingOccurrencesOfString:@"&nbsp;" withString:@" "];
    string = [string stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"];
    
    return string;
}

+ (uint8_t)adpcmEncode:(int32_t)sample reset:(int)reset {
    NSData *data = [NSData dataWithBytes:&sample length:4];
    Byte *byte1 = (Byte *) malloc(sizeof(Byte) * 4);
    [data getBytes:byte1 length:4];
    Byte *byte2 = (Byte *) malloc(sizeof(Byte) * 4);
    
    byte2[0] = byte1[0];
    byte2[1] = byte1[1];
    byte2[2] = byte1[2];
    byte2[3] = byte1[3];
    
    NSData *data2 = [NSData dataWithBytes:byte2 length:4];
    int32_t sample2 = 0;
    [data2 getBytes:&sample2 length:4];
    NSLog(@"%@ data2:%@", data, data2);
    return ADPCM_Encode(sample2, reset);
}

+ (NSData *)adpcmEncodeData:(NSData *)data {
    Byte *byte1 = (Byte *) malloc(data.length);
    [data getBytes:byte1 length:data.length];
    Byte *byte2 = (Byte *) malloc(data.length);
    
    int len = CompressFile(byte1, (uint32_t)data.length, byte2, (uint32_t)data.length);
    
    return [NSData dataWithBytes:byte2 length:len / 4];
}

//Optional("1.2.4(MT)  1.0.9(BT)")------------------Optional("mt1.2.5&bt1.0.9")
+ (NSString *)returnUploadWith:(NSString *)localVersion ServerVersion:(NSString *)serverVersion {
    
    NSArray *localVersionAry = [localVersion componentsSeparatedByString:@" "];
    NSArray *serverVersionAry = [serverVersion componentsSeparatedByString:@"&"];
    NSString *localMT = [localVersionAry.firstObject stringByReplacingOccurrencesOfString:@"(MT)" withString:@""];
    localMT = [localMT stringByReplacingOccurrencesOfString:@"." withString:@""];
    NSString *localBT = [localVersionAry.lastObject stringByReplacingOccurrencesOfString:@"(BT)" withString:@""];
    localBT = [localBT stringByReplacingOccurrencesOfString:@"." withString:@""];
    NSString *serverMT = [serverVersionAry.firstObject stringByReplacingOccurrencesOfString:@"mt" withString:@""];
    serverMT = [serverMT stringByReplacingOccurrencesOfString:@"." withString:@""];
    NSString *serverBT = [serverVersionAry.lastObject stringByReplacingOccurrencesOfString:@"bt" withString:@""];
    serverBT = [serverBT stringByReplacingOccurrencesOfString:@"." withString:@""];
    
    NSString *result = @"";
    if (([serverMT floatValue] > [localMT floatValue]) && ([serverBT floatValue] > [localBT floatValue])) {
        result = @"mt-bt";
    }
    if (([serverMT floatValue] > [localMT floatValue]) && !([serverBT floatValue] > [localBT floatValue])) {
        result = @"mt";
    }
    if (!([serverMT floatValue] > [localMT floatValue]) && ([serverBT floatValue] > [localBT floatValue])) {
        result = @"bt";
    }
    if (!([serverMT floatValue] > [localMT floatValue]) && !([serverBT floatValue] > [localBT floatValue])) {
        result = @"";
    }
    
    return result;
}

/// 判断是否是最新版本
+ (BOOL)isTheVersion:(NSString *)tVersion newerThanAnotherVersion:(NSString *)aVersion {
    
    BOOL newer = NO;
    NSArray *aVersions = [aVersion componentsSeparatedByString:@"."];
    NSArray *tVersions = [tVersion componentsSeparatedByString:@"."];
    NSString *headStr = aVersions.firstObject;
    NSString *firstStr = [[NSString alloc] init];
    firstStr = headStr;
    if([headStr hasPrefix:@"v"] || [headStr hasPrefix:@"V"]) {
        firstStr = [headStr substringFromIndex:1];
    }
    
    if(aVersions[0] )
    if (aVersions.count < 3) {
        return YES;
    }
    if ([tVersions[0] intValue] < firstStr.intValue) {
        newer = NO;
    } else if ([tVersions[0] intValue] > firstStr.intValue) {
        newer = YES;
    } else {
        if ([tVersions[1] intValue] < [aVersions[1] intValue]) {
            newer = NO;
        } else if ([tVersions[1] intValue] > [aVersions[1] intValue]) {
            newer = YES;
        } else {
            if ([tVersions[2] intValue] < [aVersions[2] intValue]) {
                newer = NO;
            } else {
                newer = YES;
            }
        }
    }
    
    return newer;
}

+ (NSData *)hexDataFromString:(NSString *)string {
    NSInteger len = [string length] / 2;    // Target length
    unsigned char *buf = malloc(len);
    unsigned char *whole_byte = buf;
    char byte_chars[3] = {'\0', '\0', '\0'};
    
    int i;
    for (i = 0; i < [string length] / 2; i++) {
        byte_chars[0] = [string characterAtIndex:i * 2];
        byte_chars[1] = [string characterAtIndex:i * 2 + 1];
        *whole_byte = strtol(byte_chars, NULL, 16);
        whole_byte++;
    }
    
    NSData *data = [NSData dataWithBytes:buf length:len];
    free(buf);
    return data;
}

+ (NSString *) getDeviceUUID{
    NSString *uuidIndentifier;
    if ([Keychain hasValueForKey:UUIDIdentifier]) {
        NSLog(@"Get UUID from keyChain");
        uuidIndentifier = [Keychain secureValueForKey:UUIDIdentifier];
    }else{
        NSLog(@"UUID is null, create UUID");
        NSString *uuid = [self CreateUUID];
        [Keychain setSecureValue:uuid forKey:UUIDIdentifier];
        uuidIndentifier = uuid;
    }
    NSLog(@"UUID: %@", uuidIndentifier);
    return uuidIndentifier;
}

/**
 *  创建设备UUID
 */
+ (NSString *) CreateUUID{
    CFUUIDRef sUUID = CFUUIDCreate(NULL);
    CFStringRef sUUIDStringRef = CFUUIDCreateString(NULL, sUUID);
    CFRelease(sUUID);
    NSString *sUUIDString = (__bridge NSString *)sUUIDStringRef;
    return sUUIDString;
}

// 新协议

// 字符串转化为data -- sn字符串转data
+ (NSData *)convertHexStrToData:(NSString *)str
{
    if (!str || [str length] == 0) {
        return nil;
    }
    // 大小端转换
    NSString *tempStr = @"";
    for (int i = 0; i < str.length / 2; i ++) {
        tempStr = [tempStr stringByAppendingString:[str substringWithRange:NSMakeRange((str.length/2 - i - 1)*2, 2)]];
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:20];
    NSRange range;
    if ([tempStr length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [tempStr length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [tempStr substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    NSLog(@"字符串转data结果：--%@-----------------%@",str,hexData);
    return hexData;
}

// 十进制转十六进制
+ (NSString *)ToHex:(long long int)tmpid
{
    NSString *nLetterValue;
    NSString *str =@"";
    long long int ttmpig;
    for (int i = 0; i<9; i++) {
        ttmpig=tmpid%16;
        tmpid=tmpid/16;
        switch (ttmpig)
        {
            case 10:
                nLetterValue =@"A";break;
            case 11:
                nLetterValue =@"B";break;
            case 12:
                nLetterValue =@"C";break;
            case 13:
                nLetterValue =@"D";break;
            case 14:
                nLetterValue =@"E";break;
            case 15:
                nLetterValue =@"F";break;
            default:nLetterValue=[[NSString alloc]initWithFormat:@"%lli",ttmpig];
                
        }
        str = [nLetterValue stringByAppendingString:str];
        if (tmpid == 0) {
            break;
        }
    }
    return str;
}

/*
 *规则： 先将字符串转成ascll码并转换大小端，然后将次字符串转化为data就可以了。
 */
+ (NSData *)strToAscll:(NSString *)str {
    
    NSUInteger length = str.length;
    NSString *codeStr = @"";
    // 一个字节一个字节的转的 - 不支持“ff”作为一个字符转化。
    for (int i = 0; i < length; i++) {
        
        uint8_t ascllCode = [str characterAtIndex:length - i - 1];
        codeStr = [NSString stringWithFormat:@"%@%@",codeStr,[self ToHex:ascllCode]];
    }
    NSLog(@"字符串转数据 ============= %@ =====",codeStr);
    NSData *data = [self convertHexStrToData:codeStr];
    return data;
}

+ (NSString *)convertDataToHexStr:(NSData *)data {
    NSLog(@"要转化的ascll码 =============== %@",data);
    NSString *str = @"";
    Byte *bytes = (Byte *) malloc(data.length);
    [data getBytes:bytes length:data.length];
    
    for (int i = 0; i < data.length; i ++) {
        char temp = bytes[i];
        str = [str stringByAppendingString:[NSString stringWithFormat:@"%c",temp]];
    }
    NSLog(@"ascll码转化的结果 ===============%@",str);
    
    return str;
    
}
// 适配iOS13的data转字符串
+ (NSString*)dataChangeToString:(NSData*)data{
    if (@available(iOS 13.0, *)) {
        NSMutableString *mutableString = [NSMutableString string];
        const char *bytes = data.bytes;
        NSInteger count = data.length;
        for (int i = 0; i < count; i++) {
            [mutableString appendFormat:@"%0.2hhx", bytes[i]];
        }
        return (NSString *)mutableString;
    } else {
        NSString * string = [NSString stringWithFormat:@"%@",data];
        string = [string stringByReplacingOccurrencesOfString:@"<" withString:@""];
        string = [string stringByReplacingOccurrencesOfString:@">" withString:@""];
        string = [string stringByReplacingOccurrencesOfString:@" " withString:@""];
        return string;
    }
}

+ (int32_t)change:(int32_t)value {
    return ((value & 0x000000FF) << 24) |  ((value & 0x0000FF00) << 8) |  ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24);
}

+ (NSDictionary *)returnCarDevices:(NSString *)carType {
    if (IMTCarSeriesV(carType)) {
        return @{@"PC":@(0x20),@"MC":@(0x21)};
    }
    if (IMTCarSeriesVX(carType)) {
        return @{@"HMZC":@(0x21),@"MC":@(0x22),@"BT":@(0x23)};
    }
    if (IMTCarSeriesP(carType)) {
        return @{@"BT":@(0x30)};
    }
    if (IMTCarSeriesL(carType)) {
        return @{@"PC":@(0x30),@"MC":@(0x31)};
    }
    if (IMTCarSeriesLorin(carType)) {
        return @{@"MC":@(0x31),@"BT":@(0x32)};
    }
    if (IMTCarSeriesR0(carType)) {
        return @{@"MC":@(0x0a),@"BT":@(0x0b)};
    }
    if (IMTCarSeriesR1(carType) || IMTCarSeriesR2(carType) || IMTCarSeriesB2(carType) || IMTCarSeriesD1(carType) || IMTCarSeriesD2(carType) || IMTCarSeriesD2F(carType)) {
        return @{@"PC":@(0x10),@"MC":@(0x11)};
    }
    return nil;
}

//获取当前时间戳字符串
+ (NSString *)getTimestampSince1970 {
    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
    NSString *timeSp = [NSString stringWithFormat:@"%.0f",interval];
    return timeSp;
}

@end
